#include "Operate.h"

MyChar* Creat_MyChar(char* p) {
    if(NULL == p) {
        return NULL;
    }
    MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
    if(NULL == mychar) {
        return NULL;
    }

    mychar->p = p;

    return mychar;
}

// 先识别数字
int Is_Number(char c) {
    return c >= '0' && c <= '9';
}

// 识别左括号
int Is_Left(char c) {
    return c == '(';
}

// 识别右括号
int Is_Right(char c) {
    return ')' == c;
}

// 识别时不时运算符
int Is_Operator(char c) {
    return '+' == c || '-' == c || '*' == c || '/' == c;
}

// 判断运算符的优先级
int Get_Priority(char c) {
    if('+' == c || '-' == c) {
        return 1;
    }

    if('*' == c || '/' == c) {
        return 2;
    }

    return 0;
}

// 处理数字、左括号、右括号的操作
void Number_Operatr(char* p) {
    printf("%c", *p);
}

// 左括号的操作 --> 入栈
void Left_Operate(LinkStack* stack, char* p) {
    if(NULL == stack || NULL == p) {
        return ;
    }

    Push_LinkStack(stack, (LinkNode*)Creat_MyChar(p));
}

// 对右括号的操作 --> 挨个弹出栈顶元素并输出，直到匹配到左括号
void Right_Operate(LinkStack* stack) {
    if(NULL == stack) {
        return ;
    }

    while(GetSize_LinkStack(stack) > 0) {
        MyChar* mychar = (MyChar*)Top_LinkStack(stack);

        // 判断是不是左括号，是左括号，没必要输出，且右括号操作结束
        if(Is_Left(*(mychar->p))) {
            Pop_LinkStack(stack);
            free(mychar);

            break;
        }

        // 如果不是左括号，则输出处理
        printf("%c", *(mychar->p));
        Pop_LinkStack(stack);
        free(mychar);
    }
}

// 运算符的操作: 要用拿到的运算符和栈顶运算符做比较
void Operator_Operate(LinkStack* stack, char* p) {
    if(NULL == stack || NULL == p) {
        return ;
    }

    // 先取出栈顶运算符
    MyChar* mychar = (MyChar*)Top_LinkStack(stack);

    // 如果此时 mychar == NULL，则栈是空栈，直接入栈即可
    if(NULL == mychar) {
        Push_LinkStack(stack, (LinkNode*)Creat_MyChar(p));
        return ;
    }

    // 如果不是空栈，那么需要比较当前字符和栈顶字符的优先级
    // 如果栈顶字符优先级低，直接入栈
    if(Get_Priority(*(mychar->p)) < Get_Priority(*p)) {
        Push_LinkStack(stack, (LinkNode*)Creat_MyChar(p));
    } else {
        // 栈顶符号优先级不低  --> 等于或者大于
        // 此时，栈顶符号出栈
        MyChar* mychar2 = NULL;
        // 出栈前决定栈是不是空栈
        while(GetSize_LinkStack(stack) > 0) {
            mychar2 = (MyChar*)Top_LinkStack(stack);

            // 再一次做优先级比较
            // 栈顶优先级低，则入栈
            // 不低，则持续出栈
            if(Get_Priority(*(mychar2->p)) < Get_Priority(*p)) {
                Push_LinkStack(stack, (LinkNode*)Creat_MyChar(p));
                return ;
            }

            // 输出出栈的栈顶元素
            printf("%c", *(mychar2->p));
            Pop_LinkStack(stack);
            free(mychar2);
        }
    }
}
